package com.ciba.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciba.demo.mapper.SysWordMapper;
import com.ciba.demo.mapper.WordSelectedMapper;
import com.ciba.demo.pojo.SysWord;
import com.ciba.demo.pojo.UserInfo;
import com.ciba.demo.pojo.UserPlan;
import com.ciba.demo.pojo.WordSelected;
import com.ciba.demo.respone.ApiRestResponse;
import com.ciba.demo.service.WordService;
import com.ciba.demo.vo.ReciteWord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Repository
public class WordServiceImpl implements WordService {

    private static String ReCiteWords = "ReCiteWords" ;
    private static String ReViewWords = "ReViewWords" ;
    private static String Record = "Record" ;
    private static Random random = new Random() ;

    @Autowired
    private WordSelectedMapper wordSelectedMapper ;

    @Autowired
    private SysWordMapper sysWordMapper ;

    @Resource
    private RedisTemplate redisTemplate ;

    @Resource
    private PlanServiceImpl planService  ;

    @Override
    public ApiRestResponse getReviewWordChineseToEnglish(HttpServletRequest request, HttpServletResponse response) {
        UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user") ;
        return getReviewWord(userInfo,1);
    }

    @Override
    public ApiRestResponse getReciteWordChineseToEnglish(HttpServletRequest request, HttpServletResponse response) {
        UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user") ;
        return getReciteWord(userInfo,1);
    }

    @Override
    public ApiRestResponse getReviewWordEnglishToChinese(HttpServletRequest request, HttpServletResponse response) {
        UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user") ;
        return getReviewWord(userInfo,2);
    }

    @Override
    public ApiRestResponse getReciteWordEnglishToChinese(HttpServletRequest request, HttpServletResponse response) {
        UserInfo userInfo = (UserInfo) request.getSession().getAttribute("user") ;
        return getReciteWord(userInfo,2);
    }

    //背诵的
    public ApiRestResponse getReciteWord(UserInfo user, int type) {
        String name = ReCiteWords+"_"+user.getId() ;
        boolean cite = redisTemplate.hasKey(name) ;
        if(!cite){
            UserPlan userPlan = planService.getPlan(user) ;
            setReCiteWords(userPlan);
        }
        int index = (int)redisTemplate.opsForValue().get(name+"nub") ;
        if(index!=0){
            redisTemplate.opsForValue().set(name+"nub",index-1);
            SysWord words = (SysWord)redisTemplate.boundListOps(name).index(index-1) ;
            if(type==1){
                SysWord sysWord = getWordForChineseToEnglish(name,index) ;
                return ApiRestResponse.success().setData(sysWord).setStatus(1) ;
            }else{
                ReciteWord reciteWord = getWordForEnglishToChinese(name,index) ;
                return ApiRestResponse.success().setData(reciteWord).setStatus(1) ;
            }
        }
        return  ApiRestResponse.success().setStatus(2).setMsg("今天已经没单词可背了！");
    }

    //复习的
    public ApiRestResponse getReviewWord(UserInfo user,int type) {
        String name = ReViewWords +"_" +user.getId() ;
        if(!redisTemplate.hasKey(name)||(Integer)redisTemplate.opsForValue().get(name+"nub")==0){
            setReView(user);
        }
        int index = (int)redisTemplate.opsForValue().get(name+"nub") ;
       if(type==2){
           ReciteWord reciteWord = getWordForEnglishToChinese(name,index) ;
           return ApiRestResponse.success().setStatus(1).setData(reciteWord);
       }else{
           SysWord sysWord = getWordForChineseToEnglish(name,index);
           return ApiRestResponse.success().setStatus(1).setData(sysWord) ;
       }
    }

    private SysWord getWordForChineseToEnglish(String name,int index){
        redisTemplate.opsForValue().set(name+"nub",index-1);
        SysWord sysWord = (SysWord) redisTemplate.boundListOps(name).index(index-1) ;
        return  sysWord ;
    }

    private ReciteWord getWordForEnglishToChinese(String name,int index){
        redisTemplate.opsForValue().set(name+"nub",index-1);
        ReciteWord reciteWord = new ReciteWord() ;
        reciteWord.setWord((SysWord)redisTemplate.boundListOps(name).index(index-1));
        SysWord word = (SysWord)redisTemplate.boundListOps(name).index(random.nextInt(29)) ;
        reciteWord.setCh2(word.getChinese());
        word = (SysWord)redisTemplate.boundListOps(name).index(random.nextInt(29)) ;
        reciteWord.setCh3(word.getChinese());
        word = (SysWord)redisTemplate.boundListOps(name).index(random.nextInt(29)) ;
        reciteWord.setCh4(word.getChinese());
        return reciteWord ;
    }

    @Override
    public ApiRestResponse report(HttpServletRequest request, HttpServletResponse response) {
        UserInfo user = (UserInfo) request.getSession().getAttribute("user") ;
        UserPlan userPlan = planService.getPlan(user) ;
        int wordId = Integer.parseInt(request.getParameter("wordId")) ;
        String name = Record+"_"+user.getId() ;
        if(!redisTemplate.hasKey(name)){
            setRecord(user);
        }
        WordSelected wordSelected = getWordSelected(wordId,user.getId()) ;
        if(wordSelected==null){
            wordSelected = new WordSelected() ;
            wordSelected.setWordId(wordId) ;
            wordSelected.setLevel(userPlan.getBook()==1?4 : 6);
            wordSelected.setUserId(user.getId());
            wordSelected.setProficiency(1);
        }else{
            wordSelected.setProficiency(wordSelected.getProficiency()+1);
        }
        redisTemplate.boundListOps(name).leftPush(wordSelected);
        return  ApiRestResponse.success().setMsg("回流成功") ;
    }


    WordSelected getWordSelected(int wordId,int userId){
        QueryWrapper<WordSelected> wrapper = new QueryWrapper<>();
        Map<String,Object> map = new HashMap<>();
        map.put("word_id",wordId);
        map.put("user_id",userId);
        wrapper.allEq(map);
        return (WordSelected) wordSelectedMapper.selectOne(wrapper) ;
    }

    public void setReView(UserInfo userInfo) {
        UserPlan userPlan = planService.getPlan(userInfo) ;
        String name = ReViewWords +"_" +userInfo.getId() ;
        QueryWrapper<SysWord> wrapper = new QueryWrapper<>() ;
        int endWord = userPlan.getNextWord() ;
        if(endWord<30){
            wrapper.ge("id",30) ;
        }else{
            wrapper.lt("id",endWord);
        }
        wrapper.last("limit 30") ;
        List<SysWord> list = sysWordMapper.selectList(wrapper) ;
        for(int i=0;i<list.size();i++){
            redisTemplate.boundListOps(name).leftPush(list.get(i)) ;
        }
        redisTemplate.opsForValue().set(name+"nub",list.size());
    }



    public void setReCiteWords(UserPlan userPlan) {
        int userId = userPlan.getUserId() ;
        String level = userPlan.getBook()==1 ? "4" : "6" ;
        int nubReview = userPlan.getReview() ;
        int endWord = userPlan.getNextWord() ;
        List<SysWord> reViewList = new ArrayList<>() ;
        QueryWrapper<SysWord> wrapper = new QueryWrapper<>() ;
        if(nubReview>endWord){
            wrapper.lt("id",nubReview);
        }else{
            wrapper.lt("id",endWord);
        }
        wrapper.last("limit "+nubReview);
        List<SysWord> list = sysWordMapper.selectList(wrapper);
        for(int i=0;i<list.size();i++){
            redisTemplate.boundListOps(ReCiteWords+"_"+userId).leftPushAll(list.get(i)) ;
        }

        /*---------------------------------------------------------------------------*/
        int nubRecite = userPlan.getRecite() ;
        wrapper = new QueryWrapper<>() ;
        HashMap map = new HashMap<>() ;
        map.put("level",level) ;
        wrapper.allEq(map);
        wrapper.ge("id",endWord);
        wrapper.last("limit "+nubRecite);
        ArrayList<SysWord> wordList = (ArrayList) sysWordMapper.selectList(wrapper) ;
        for(int i=0;i<wordList.size();i++){
            redisTemplate.boundListOps(ReCiteWords+"_"+userId).leftPushAll(wordList.get(i)) ;
        }
        redisTemplate.opsForValue().set(ReCiteWords+"_"+userId+"nub",wordList.size()+ list.size());
    }

    public void setRecord(UserInfo userInfo) {
        int userId = userInfo.getId() ;
        redisTemplate.boundListOps(Record+"_"+userId);
    }
}
